/*
 * @Author: Zhouhai 497675647@qq.com
 * @Date: 2022-11-17 16:56:43
 * @LastEditors: Zhouhai 497675647@qq.com
 * @LastEditTime: 2022-11-25 17:21:05
 */
import { arrToTree, arrTotreeNoPID } from '@/utils/tree';
import { Modal, Transfer, Tree } from 'antd';
import type { ListStyle, TransferDirection } from 'antd/es/transfer';
import type { DataNode } from 'antd/es/tree';
import { useEffect, useState } from 'react';

interface TreeTransferProps {
    isModalOpen: boolean;
    dataSource: any[];
    targetKeys: string[];
    onChange?: (targetKeys: string[], direction: TransferDirection, moveKeys: string[]) => void;
    onOk: (targetKeys: string[]) => void;
    onCancel: () => void;
}


const TreeTransfer = ({ isModalOpen, dataSource, targetKeys: oldTargetKeys, onCancel, onOk, ...restProps }: TreeTransferProps) => {

    const [targetKeys, setTargetKeys] = useState<string[]>(oldTargetKeys);

    const [leftCheckKeys, setLeftCheckKeys] = useState<string[]>([]);//左侧树复选框选中的数据
    const [rightCheckKeys, setRightCheckKeys] = useState<string[]>([]);//右侧树复选框选中的数据

    useEffect(() => {
        setTargetKeys([...oldTargetKeys])
    }, [oldTargetKeys])

    const getTargetAndFatherKeys = (_targetKeys: string[]) => {
        const filterdatas = dataSource.filter((data) => {
            return _targetKeys.includes(data.key)
        })
        let fatherKeys: string[] = [];
        filterdatas.forEach((item) => {
            fatherKeys.push(...findFatherKeys(item))
        })
        fatherKeys.forEach((item)=>{
            if(!_targetKeys.includes(item)){
                _targetKeys.push(item)
            }
        })
        
        return _targetKeys
    }

    const findFatherKeys = (_data: any) => {
        let fatherKeys: string[] = [];
        if (_data.pkFather) {//如果存在
            //找到和_data父id相同的数据
            const father = dataSource.find((item) => {
                return _data.pkFather === item.key
            })
            if (father && !fatherKeys.includes(father.key)) {
                fatherKeys.push(father.key)
                fatherKeys.push(...findFatherKeys(father))
            }

        }
        return fatherKeys;
    }


    const findSourceAndFatherDatas = (sources: any[]) => {
        //找出所有缺少的上层数据
        //datas 是缺少上层数据的，需要从dataSource里面补全
        const datas = sources.filter((source) => {
            return source.pkFather && source.pkFather !== '0'  && !sources.find((item) => item.key === source.pkFather)//存在上层数据，且上层数据不在sources中
        })
        
        let fatherdatas: any[] = []
        datas.forEach(item => {
            const data = dataSource.find((data) => { return data.key === item.pkFather })
            if (data && !fatherdatas.find((t)=> t.key ===data.key )) {//如果找到了，判断一下是否已经找到过了，否则添加上
                fatherdatas.push(data)
            }
        });

        if (fatherdatas.length > 0) {//存在上游数据，在查询上游数据的上游数据
            const ttdatas = findSourceAndFatherDatas(fatherdatas);
            fatherdatas.push(...ttdatas)
        }
        return fatherdatas;

    }

    const findSourceDatas = (filteredItems: any[]) => {
        filteredItems.push(...findSourceAndFatherDatas(filteredItems))
        return filteredItems
    }

    return (
        <Modal
            open={isModalOpen}
            closable={false}
            destroyOnClose
            onCancel={onCancel}
            onOk={() => {
                onOk(targetKeys)
            }}>
            <Transfer
                {...restProps}
                showSelectAll={true}
                listStyle={(style: ListStyle) => { return { height: '340px', overflow: 'auto' } }}
                locale={{ itemUnit: '项', itemsUnit: '项', selectAll: '全选', selectInvert: '反选' }}
                titles={['未分配', '已分配']}
                targetKeys={targetKeys}
                dataSource={dataSource}
                selectedKeys={[...leftCheckKeys, ...rightCheckKeys]}
                className="tree-transfer"
                render={item => item.title!}
                onChange={(targetKeys, direction, moveKeys) => {
                    setTargetKeys(getTargetAndFatherKeys(targetKeys))
                    setLeftCheckKeys([])
                    setRightCheckKeys([])
                }}
                onSelectChange={(sourceSelectedKeys, targetSelectedKeys) => {
                    setLeftCheckKeys(sourceSelectedKeys);
                    setRightCheckKeys(targetSelectedKeys);
                }}
            >
                {({ direction, onItemSelect, selectedKeys, filteredItems }) => {
                    if (direction === 'left') {
                        return (
                            <Tree<DataNode>
                                virtual
                                height={300}
                                blockNode
                                checkable
                                autoExpandParent
                                defaultExpandAll={false}
                                checkedKeys={selectedKeys}
                                onCheck={(checkedKeysValue: any, { checked, node: { key } }) => {
                                    if (checked) {
                                        setLeftCheckKeys(checkedKeysValue);
                                    } else {
                                        setLeftCheckKeys([])
                                    }

                                }}
                                treeData={arrToTree(findSourceDatas(filteredItems), '0')
                    }
                    />
                        );
                    } else if (direction === 'right') {
                        return (
                <Tree<DataNode>
                    virtual
                    height={300}
                    blockNode
                    checkable
                    autoExpandParent={false}
                    defaultExpandAll={false}
                    checkedKeys={selectedKeys}
                    onCheck={(checkedKeysValue: any, { checked, node: { key } }) => {
                        if (checked) {
                            setRightCheckKeys(checkedKeysValue);
                        } else {
                            setRightCheckKeys([])
                        }

                    }}
                    treeData={arrTotreeNoPID(filteredItems, 'key', 'pkFather', 'children')}
                />
                );
                    }
                }}
            </Transfer>

        </Modal>

    );
};

export default TreeTransfer;